﻿<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="../helpproject.xsl" ?>
<topic template="Default" lasteditedby="Geert" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../helpproject.xsd">
  <title translate="true">Advanced property change notifications</title>
  <keywords>
    <keyword translate="true">Data</keyword>
    <keyword translate="true">Data handling</keyword>
    <keyword translate="true">INotifyPropertyChanged</keyword>
    <keyword translate="true">INotifyPropertyChanging</keyword>
  </keywords>
  <body>
    <header>
      <para styleclass="Heading1"><text styleclass="Heading1" translate="true">Advanced property change notifications</text></para>
    </header>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">Sometimes the old value is needed in case of property change event. However, the </text><link displaytype="text" defaultstyle="true" type="weblink" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx" target="_blank" styleclass="Normal" translate="true">INotifyPropertyChanged</link><text styleclass="Normal" translate="true"> interface does not provide any of this. To support this behavior, a new version of the </text><link displaytype="text" defaultstyle="true" type="weblink" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.propertychangedeventargs.aspx" target="_blank" styleclass="Normal" translate="true">PropertyChangedEventArgs</link><text styleclass="Normal" translate="true"> is created called </text><link displaytype="text" defaultstyle="true" type="topiclink" href="T_Catel_Data_AdvancedPropertyChangedEventArgs" styleclass="Normal" translate="true">AdvancedPropertyChangedEventArgs</link><text styleclass="Normal" translate="true">. This class derives from </text><link displaytype="text" defaultstyle="true" type="weblink" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.propertychangedeventargs.aspx" target="_blank" styleclass="Normal" translate="true">PropertyChangedEventArgs</link><text styleclass="Normal" translate="true"> so the interfaces are not broken, but it does add additional functionality to the software system.</text></para>
    <para styleclass="Heading1"><text styleclass="Heading1" translate="true">Getting old value automatically</text></para>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">When using the </text><link displaytype="text" defaultstyle="true" type="topiclink" href="T_Catel_Data_ModelBase" styleclass="Normal" translate="true">ModelBase</link><text styleclass="Normal" translate="true"> or </text><link displaytype="text" defaultstyle="true" type="topiclink" href="T_Catel_MVVM_ViewModelBase" styleclass="Normal" translate="true">ViewModelBase</link><text styleclass="Normal" translate="true"> classes, the old and new value of a property are automatically provided on a property change. There are two ways to get more information about a property change event.</text></para>
    <para styleclass="Heading2"><text styleclass="Heading2" translate="true">Getting more information from the inside</text></para>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">The easiest way to get more information on the inside is to override the </text><link displaytype="text" defaultstyle="true" type="topiclink" href="M_Catel_Data_ObservableObject_OnPropertyChanged_1_14e301f4" styleclass="Normal" translate="true">OnPropertyChanged</link><text styleclass="Normal" translate="true"> method. It automatically provides an instance of the </text><link displaytype="text" defaultstyle="true" type="topiclink" href="T_Catel_Data_AdvancedPropertyChangedEventArgs" styleclass="Normal" translate="true">AdvancedPropertyChangedEventArgs</link><text styleclass="Normal" translate="true">:</text></para>
    <para styleclass="Code Example"><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">protected</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">override</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">void</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">OnPropertyChanged(AdvancedPropertyChangedEventArgs</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">e)</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">{</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">}</text></para>
    <para styleclass="Heading2"><text styleclass="Heading2" translate="true">Getting mode information from the outside</text></para>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">Getting the information from outside the objects is a bit more work. This is because the </text><link displaytype="text" defaultstyle="true" type="topiclink" href="E_Catel_Data_ObservableObject_PropertyChanged" styleclass="Normal" translate="true">PropertyChanged</link><text styleclass="Normal" translate="true"> event still provides a value of the </text><link displaytype="text" defaultstyle="true" type="weblink" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.propertychangedeventargs.aspx" target="_blank" styleclass="Normal" translate="true">PropertyChangedEventArgs</link><text styleclass="Normal" translate="true"> class. Therefore, it is required to cast the value:</text></para>
    <para styleclass="Code Example"><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">private</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">void</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> OnObjectPropertyChanged(PropertyChangedEventArgs e)</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">{</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160;var advancedArgs = e </text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">as</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> AdvancedPropertyChangedEventArgs;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">if</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> (advancedArgs != </text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">null</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">)</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160;{</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160; &#160;</text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">// a value of AdvancedPropertyChangedEventArgs is now available</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160;}</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">}</text></para>
    <para styleclass="Heading1"><text styleclass="Heading1" translate="true">Providing old value manually</text></para>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">When using the dependency property a-like property registration, the old and new value are automatically provided by the classes. However, when using the </text><link displaytype="text" defaultstyle="true" type="topiclink" href="T_Catel_Data_ObservableObject" styleclass="Normal" translate="true">ObservableObject</link><text styleclass="Normal" translate="true">, the old and new value are not automatically provided. Therefore, it is possible to provide these values manually:</text></para>
    <para styleclass="Code Example"><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">private</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">string</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> _firstName;</text><br/><br/><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">public</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">string</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> FirstName</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">{</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160;get { </text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">return</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> _firstName; }</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160;set </text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160;{ </text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160; &#160;var oldValue = _firstName;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160; &#160;_firstName = value;</text><br/><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160; &#160;RaisePropertyChanged(() =&gt; FirstName, oldValue, value);</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160;}</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">}</text></para>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">When the values are not provided, the old and new value are set to </text><text styleclass="Normal" style="font-style:italic;" translate="true">null</text><text styleclass="Normal" style="font-style:normal;" translate="true">.</text></para>
    <para styleclass="Heading1"><text styleclass="Heading1" translate="true">Some sidenotes</text></para>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">As you might have noticed, the </text><link displaytype="text" defaultstyle="true" type="topiclink" href="T_Catel_Data_AdvancedPropertyChangedEventArgs" styleclass="Normal" translate="true">AdvancedPropertyChangedEventArgs</link><text styleclass="Normal" translate="true"> also provide the </text><link displaytype="text" defaultstyle="true" type="topiclink" href="P_Catel_Data_AdvancedPropertyChangedEventArgs_IsOldValueMeaningful" styleclass="Normal" translate="true">IsOldValueMeaningful</link><text styleclass="Normal" translate="true"> and the </text><link displaytype="text" defaultstyle="true" type="topiclink" href="P_Catel_Data_AdvancedPropertyChangedEventArgs_IsNewValueMeaningful" styleclass="Normal" translate="true">IsNewValueMeaningful</link><text styleclass="Normal" translate="true">. These are introduced because it is not always possible to determine the old or new value (for example, when the property name is string.Empty, there is no old value or new value). Therefore, the </text><link displaytype="text" defaultstyle="true" type="topiclink" href="P_Catel_Data_AdvancedPropertyChangedEventArgs_OldValue" styleclass="Normal" translate="true">OldValue</link><text styleclass="Normal" translate="true"> and </text><link displaytype="text" defaultstyle="true" type="topiclink" href="P_Catel_Data_AdvancedPropertyChangedEventArgs_NewValue" styleclass="Normal" translate="true">NewValue</link><text styleclass="Normal" translate="true"> properties are </text><text styleclass="Normal" style="font-style:italic;" translate="true">null</text><text styleclass="Normal" style="font-style:normal;" translate="true">, but doesn&apos;t mean that those are the actual old and new values.</text></para>
    <para styleclass="Normal"><text styleclass="Normal" style="font-style:normal;" translate="true">It is always required to check whether the values are meaningful before actually handing them:</text></para>
    <para styleclass="Code Example"><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">protected</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">override</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">void</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> OnPropertyChanged(AdvancedPropertyChangedEventArgs e)</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">{</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">if</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> (e.IsOldValueMeaningful)</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160;{</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160; &#160;</text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">// Handle old value</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160;}</text><br/><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">if</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> (e.IsNewValueMeaningful)</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160;{</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160; &#160;</text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">// Handle new value</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160;}</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">}</text></para>
  </body>
</topic>
